Dify から Bedrock Knowledge Bases に接続してみる

Dify から Bedrock Knowledge Bases に接続してみる

Clock Icon2024.12.31

こんにちは、森田です。

はじめに

先日 AWSマネージドサービスで Dify のセルフホスティングを試してみました。

https://dev.classmethod.jp/articles/dify-self-hosting-aws

このセルフホスティングについては、aws-sampleのリポジトリを利用していました。

https://github.com/aws-samples/dify-self-hosted-on-aws

ブログ執筆後改めて確認したところ、外部ナレッジベースとして Bedrock Knowledge Bases に接続できるようになっていました。

https://github.com/aws-samples/dify-self-hosted-on-aws/pull/9

なにが嬉しいか

標準の Dify のナレッジベースでは、ガッツリRAGとして利用する際には物足りないです。

https://docs.dify.ai/ja-jp/guides/knowledge-base/external-data-tool

特に、PDF内の図表からデータを読み取りたい、高度なチャンキング戦略を利用したいシーンでは、標準のナレッジベースでは実現できません。

一方で、 Bedrock Knowledge Bases では、図表からの読み取りや高度なRAG機能をサポートしています。

https://dev.classmethod.jp/articles/knowledge-bases-for-amazon-bedrock-advanced-rag-capabilities

https://dev.classmethod.jp/articles/structured-bedrock-knowledge-base

そのため、Bedrock Knowledge Bases を利用することができれば、より良いテキスト検索や検索精度向上が期待できます。

本記事では、実際に Bedrock Knowledge Bases に接続してワークフローを実行できるところまで確認してみたいと思います。

やってみた

前提条件

AWS CDK を使ってのデプロイが完了しているものとします。

https://dev.classmethod.jp/articles/dify-self-hosting-aws

また、以前デプロイされている環境の場合は、再度pullしてからデプロイが必要となります。

git pull
npx cdk deploy

AWS 側での設定

オレゴン(us-west-2)リージョンで作業を行います。

また、パースモデル(Claude 3 Haiku v1)、埋め込みモデル(Titan Text Embeddings v2)のモデルアクセスは有効化済みとします。

img.png

S3 バケットの準備

Knowledge Bases のデータソースとして S3 バケットを使いたいため、事前に作成しておきます。

img.png

続いて、動作確認用のファイルをS3バケットに格納します。

今回は、こちらのページの損益計算書の箇所を画像として取得して、PDF内に貼り付けたファイルをアップロードしました。

img.png

Bedrock Knowledge Bases の作成

コンソールからKnowledge Base with vector storeを選択して、Knowledge Bases の作成を開始します。

img.png

データソースの設定については、先ほど作成した S3 バケットを指定します。

また、PDF内の画像データから情報を取得したいため、「パース戦略」でFoundation models as a parserを選択します。

モデルは、Claude 3 Haiku v1で行います。

img_166.png

埋め込みモデルにはTitan Text Embeddings v2、ベクトルデータベースはクイック作成(Amazon OpenSearch Serverless)を選択して、ナレッジベースの作成を完了させます。

img_162.png

ナレッジベース作成後、ステータスが利用可能になったら、データソースの同期を行います。

img.png

最後に、ナレッジベースIDの入力が必要となるため、メモしておきます。

img.png

Dify 側での設定

外部ナレッジベースの追加

Dify へサインインを行います。

サインイン後、ナレッジをクリックし、「外部ナレッジベースへの接続」をクリックします。

img.png

まずは、外部ナレッジAPIの入力が求められるため、以下を入力します。

項目 設定値
API Endpoint http://localhost:8000
API Key dummy-key

img_147.png

続いて、外部ナレッジ名、説明などの入力が求められます。

外部ナレッジIDには、AWSマネジメントコンソールで確認したナレッジベースIDを入力して「繋ぐ」をクリックします。

img_151.png

ワークフローからの動作確認

知識取得→LLMのように繋いだワークフローを作成します。

img.png

ワークフローのソース
dsl.yml
app:
  description: ''
  icon: 🤖
  icon_background: '#FFEAD5'
  mode: workflow
  name: ' Knowledge_Bases_test'
  use_icon_as_answer_icon: false
kind: app
version: 0.1.5
workflow:
  conversation_variables: []
  environment_variables: []
  features:
    file_upload:
      allowed_file_extensions:
      - .JPG
      - .JPEG
      - .PNG
      - .GIF
      - .WEBP
      - .SVG
      allowed_file_types:
      - image
      allowed_file_upload_methods:
      - local_file
      - remote_url
      enabled: false
      fileUploadConfig:
        audio_file_size_limit: 50
        batch_count_limit: 5
        file_size_limit: 15
        image_file_size_limit: 10
        video_file_size_limit: 100
        workflow_file_upload_limit: 10
      image:
        enabled: false
        number_limits: 3
        transfer_methods:
        - local_file
        - remote_url
      number_limits: 3
    opening_statement: ''
    retriever_resource:
      enabled: true
    sensitive_word_avoidance:
      enabled: false
    speech_to_text:
      enabled: false
    suggested_questions: []
    suggested_questions_after_answer:
      enabled: false
    text_to_speech:
      enabled: false
      language: ''
      voice: ''
  graph:
    edges:
    - data:
        isInIteration: false
        sourceType: start
        targetType: knowledge-retrieval
      id: 1735650006099-source-1735650121261-target
      source: '1735650006099'
      sourceHandle: source
      target: '1735650121261'
      targetHandle: target
      type: custom
      zIndex: 0
    - data:
        isInIteration: false
        sourceType: knowledge-retrieval
        targetType: llm
      id: 1735650121261-source-1735650321747-target
      source: '1735650121261'
      sourceHandle: source
      target: '1735650321747'
      targetHandle: target
      type: custom
      zIndex: 0
    - data:
        isInIteration: false
        sourceType: llm
        targetType: end
      id: 1735650321747-source-1735650673261-target
      source: '1735650321747'
      sourceHandle: source
      target: '1735650673261'
      targetHandle: target
      type: custom
      zIndex: 0
    nodes:
    - data:
        desc: ''
        selected: false
        title: 開始
        type: start
        variables:
        - label: text
          max_length: 48
          options: []
          required: true
          type: text-input
          variable: text
      height: 90
      id: '1735650006099'
      position:
        x: 79
        y: 282
      positionAbsolute:
        x: 79
        y: 282
      selected: false
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 244
    - data:
        dataset_ids:
        - 719b7365-0eaa-4850-930b-00f8386263e7
        desc: ''
        multiple_retrieval_config:
          reranking_enable: false
          reranking_mode: reranking_model
          reranking_model:
            model: cohere.rerank-v3-5:0
            provider: bedrock
          score_threshold: null
          top_k: 4
        query_variable_selector:
        - '1735650006099'
        - text
        retrieval_mode: multiple
        selected: false
        title: 知識取得
        type: knowledge-retrieval
      height: 92
      id: '1735650121261'
      position:
        x: 448
        y: 282
      positionAbsolute:
        x: 448
        y: 282
      selected: true
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 244
    - data:
        context:
          enabled: true
          variable_selector:
          - '1735650121261'
          - result
        desc: ''
        model:
          completion_params:
            temperature: 0.7
          mode: chat
          name: anthropic.claude-3-haiku-20240307-v1:0
          provider: bedrock
        prompt_template:
        - id: 58119e4c-658c-4060-814a-67acd5b87580
          role: system
          text: 'あなたは世界中で信頼されているQAシステムです。

            事前知識ではなく、常に提供されたコンテキスト情報を使用してクエリに回答してください。

            従うべきいくつかのルール:

            1. 回答内で指定されたコンテキストを直接参照しないでください。

            2. 「コンテキストに基づいて、...」や「コンテキスト情報は...」、またはそれに類するような記述は避けてください。'
        - id: 5dcbc502-3cc2-4d78-85bd-513c41299269
          role: user
          text: 'コンテキスト情報は以下のとおりです。


            ----

            {{#context#}}

            ----

            事前知識ではなくコンテキスト情報を考慮して、質問に答えます。

            Query: {{#1735650006099.text#}}


            Answer: '
        selected: false
        title: LLM
        type: llm
        variables: []
        vision:
          enabled: false
      height: 98
      id: '1735650321747'
      position:
        x: 767
        y: 282
      positionAbsolute:
        x: 767
        y: 282
      selected: false
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 244
    - data:
        desc: ''
        outputs:
        - value_selector:
          - '1735650321747'
          - text
          variable: text
        selected: false
        title: 終了
        type: end
      height: 90
      id: '1735650673261'
      position:
        x: 1071
        y: 282
      positionAbsolute:
        x: 1071
        y: 282
      selected: false
      sourcePosition: right
      targetPosition: left
      type: custom
      width: 244
    viewport:
      x: 77.12622572005426
      y: 53.94683253832943
      zoom: 0.7924181916245135

公開を行い、アプリケーションから動作確認を行います。

まずは、「FY2020の売上高を教えて」と入力してみます。

すると、正常にナレッジベースの情報を使って回答してくれることを確認できます。

img.png

続いて、「FY2025の売上高を教えて」と入力してみます。

今度は、該当のデータがない旨の回答をしてくれました。

img.png

さいごに

Bedrock Knowledge Bases を外部ナレッジベースとして利用できることで、Dify の標準機能では難しかった高度な検索要件にも対応できます。

特に、RAGを本格的に活用したい開発者にとって非常に有用です。

さらに、通常であれば外部APIの開発などが必要になりますが、CDKによってIaC化されているため、手軽に導入できる点も魅力的です。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.